package user;

import command.RemoteController;
import factory.FarmSystemManager;
import factory.Task;
import model.FarmMachine;
import monitor.EnvironmentMonitor;
import safety.SafetyController;
import safety.SafetyEvent;
import observer.*;

import strategy.*;



import java.util.Scanner;

/**
 * 用户输入处理器
 * 处理用户输入的环境数据、安全事件和任务分配
 */
public class UserInputHandler {

    private EnvironmentMonitor monitor;
    private FarmSystemManager manager;
    private SafetyController safetyController;
    private Scanner scanner;
    // 环境监测相关组件
    private SoilMoistureSensor soilMoistureSensor;
    private RoadblockSensor roadblockSensor;
    private SoilPHSensor soilPHSensor;
    private SoilNutrientSensor soilNutrientSensor;
    private TemperatureSensor temperatureSensor;
    private HumiditySensor humiditySensor;
    private WindSpeedSensor windSpeedSensor;
    private CropGrowthMonitor cropGrowthMonitor;
    private RemoteController remoteController; // 新增遥控器对象
    private PathPlanningStrategy pathStrategy; // 新增路径规划策略对象
    public UserInputHandler(EnvironmentMonitor monitor, FarmSystemManager manager,
                            SafetyController safetyController, RoadblockSensor roadblockSensor) {
        this.monitor = monitor;
        this.manager = manager;
        this.safetyController = safetyController;
        this.roadblockSensor = roadblockSensor;
        this.scanner = new Scanner(System.in);
        this.remoteController = null;
        this.pathStrategy = new Path(); // 初始化路径规划策略对象
        // 初始化环境监测组件
        this.soilMoistureSensor = new SoilMoistureSensor();
        this.soilPHSensor = new SoilPHSensor();
        this.soilNutrientSensor = new SoilNutrientSensor();
        this.temperatureSensor = new TemperatureSensor();
        this.humiditySensor = new HumiditySensor();
        this.windSpeedSensor = new WindSpeedSensor();
        this.cropGrowthMonitor = new CropGrowthMonitor("小麦");


        // 注册设备观察者
        for (FarmMachine machine : manager.getEquipmentList()) {
            soilMoistureSensor.addObserver(machine);
            temperatureSensor.addObserver(machine);
            humiditySensor.addObserver(machine);
        }
        // 将路径规划策略对象注册为传感器的观察者
        roadblockSensor.addObserver(pathStrategy);
        humiditySensor.addObserver(pathStrategy);
    }
    public void showMenu() {
        while (true) {
            System.out.println("\n===== 智能农机系统 =====");
            System.out.println("1. 环境监测数据输入");
            System.out.println("2. 作物生长监测");
            System.out.println("3. 处理安全事件");
            System.out.println("4. 分配任务");
            System.out.println("5. 农机状态");
            System.out.println("6. 撤销上一步操作");
            System.out.println("7. 设备控制");
            System.out.println("8. 退出");
            System.out.print("请选择操作 [1-8]: ");

            if (scanner.hasNextInt()) {
                int choice = scanner.nextInt();
                scanner.nextLine();// 消耗换行符

                switch (choice) {
                    case 5:
                        displayEquipmentList();
                    break;
                    case 1:
                        inputEnvironmentalData();
                        break;
                    case 7:
                        controlEquipment();
                        break;
                    case 4:
                        assignTask();
                        break;
                    case 3:
                        handleSafetyEvent();
                        break;
                    case 2:
                        monitorCropGrowth();
                        break;
                    case 6:
                        undoLastOperation();
                        break;
                    case 8:
                        System.out.println("退出系统...");
                        return;
                    default:
                        System.out.println("无效选择，请重新输入！");
                }
            } else {
                String invalidInput = scanner.next();
                System.out.println("输入错误: \"" + invalidInput + "\" 不是有效的数字，请重新输入。");
            }
        }
    } // 环境监测数据输入
    private void inputEnvironmentalData() {
        System.out.println("\n===== 环境监测数据输入 =====");
        System.out.println("请依次输入以下数据（可随时输入 's' 跳过当前项）");

        // 依次输入各类环境数据
        inputSoilMoisture();
        inputSoilPH();
        inputSoilNutrients();
        inputTemperature();
        inputHumidity();
        inputWindSpeed();
        System.out.println("环境数据输入完成");
    }
    //路障输入
    private void inputPathAvoid(){
        System.out.print("\n输入路障大小（米，输入's'跳过）: ");
        String input = scanner.nextLine().toLowerCase();
        if (!input.equals("s")) {
            try {
                double size = Double.parseDouble(input);
                if (size <= 0) {
                    throw new IllegalArgumentException("路障大小必须大于0");
                }
                roadblockSensor.setValue(Double.parseDouble(input));

                System.out.println("障碍物为 " + input + "%");
                // 创建障碍物并触发避障逻辑

            } catch (IllegalArgumentException e) {
                throw new RuntimeException(e);
            }
        }
    }

    // 土壤湿度输入
    private void inputSoilMoisture() {
        System.out.print("\n输入土壤湿度（0-100，输入's'跳过）: ");
        String input = scanner.nextLine().toLowerCase();
        if (!input.equals("s")) {
            try {
                double moisture = Double.parseDouble(input);
                if (moisture < 0 || moisture > 100) {
                    throw new IllegalArgumentException();
                }
                soilMoistureSensor.setValue(moisture);
                System.out.println("土壤湿度更新为: " + moisture + "%");
            } catch (Exception e) {
                System.out.println("输入无效，跳过土壤湿度输入");
            }
        }
    }
    // 土壤pH值输入
    private void inputSoilPH() {
        System.out.print("输入土壤pH值（4.0-9.0，输入's'跳过）: ");
        String input = scanner.nextLine().toLowerCase();
        if (!input.equals("s")) {
            try {
                double ph = Double.parseDouble(input);
                if (ph < 4.0 || ph > 9.0) {
                    throw new IllegalArgumentException();
                }
                soilPHSensor.setValue(ph);
                System.out.println("土壤pH值更新为: " + ph);
            } catch (Exception e) {
                System.out.println("输入无效，跳过土壤pH值输入");
            }
        }
    }// 土壤养分输入
    private void inputSoilNutrients() {
        System.out.println("\n--- 土壤养分输入 ---");
        boolean skip = false;

        // 氮含量
        System.out.print("输入氮含量（mg/kg，输入's'跳过）: ");
        String nitrogenInput = scanner.nextLine().toLowerCase();
        if (!nitrogenInput.equals("s")) {
            try {
                double nitrogen = Double.parseDouble(nitrogenInput);
                soilNutrientSensor.getSensor("氮").setValue(nitrogen);
            } catch (Exception e) {
                System.out.println("氮含量输入无效，跳过");
                skip = true;
            }
        }

        if (!skip) {
            // 磷含量
            System.out.print("输入磷含量（mg/kg，输入's'跳过）: ");
            String phosphorusInput = scanner.nextLine().toLowerCase();
            if (!phosphorusInput.equals("s")) {
                try {
                    double phosphorus = Double.parseDouble(phosphorusInput);
                    soilNutrientSensor.getSensor("磷").setValue(phosphorus);
                } catch (Exception e) {
                    System.out.println("磷含量输入无效，跳过");
                    skip = true;
                }
            }
        }

        if (!skip) {
            // 钾含量
            System.out.print("输入钾含量（mg/kg，输入's'跳过）: ");
            String potassiumInput = scanner.nextLine().toLowerCase();
            if (!potassiumInput.equals("s")) {
                try {
                    double potassium = Double.parseDouble(potassiumInput);
                    soilNutrientSensor.getSensor("钾").setValue(potassium);
                } catch (Exception e) {
                    System.out.println("钾含量输入无效，跳过");
                }
            }
        }
    }// 温度输入
    private void inputTemperature() {
        System.out.print("\n输入温度（-20-40℃，输入's'跳过）: ");
        String input = scanner.nextLine().toLowerCase();
        if (!input.equals("s")) {
            try {
                double temperature = Double.parseDouble(input);
                if (temperature < -20 || temperature > 40) {
                    throw new IllegalArgumentException();
                }
                temperatureSensor.setValue(temperature);
                System.out.println("温度更新为: " + temperature + "℃");
            } catch (Exception e) {
                System.out.println("输入无效，跳过温度输入");
            }
        }
    }
    // 空气湿度输入
    private void inputHumidity() {
        System.out.print("输入空气湿度（0-100，输入's'跳过）: ");
        String input = scanner.nextLine().toLowerCase();
        if (!input.equals("s")) {
            try {
                double humidity = Double.parseDouble(input);
                if (humidity < 0 || humidity > 100) {
                    throw new IllegalArgumentException();
                }
                humiditySensor.setValue(humidity);
                System.out.println("空气湿度更新为: " + humidity + "%");
            } catch (Exception e) {
                System.out.println("输入无效，跳过湿度输入");
            }
        }
    }// 风速输入
    private void inputWindSpeed() {
        System.out.print("输入风速（0-30m/s，输入's'跳过）: ");
        String input = scanner.nextLine().toLowerCase();
        if (!input.equals("s")) {
            try {
                double windSpeed = Double.parseDouble(input);
                if (windSpeed < 0 || windSpeed > 30) {
                    throw new IllegalArgumentException();
                }
                windSpeedSensor.setValue(windSpeed);
                System.out.println("风速更新为: " + windSpeed + "m/s");
            } catch (Exception e) {
                System.out.println("输入无效，跳过风速输入");
            }
        }
    }// 作物生长监测
    private void monitorCropGrowth() {
        System.out.println("\n===== 作物生长监测 =====");
        System.out.println("1. 查看当前作物状态");
        System.out.println("2. 更新作物高度");
        System.out.println("3. 更新作物生长阶段");
        System.out.println("4. 自动模拟生长");
        System.out.println("5. 返回主菜单");
        System.out.print("请选择操作 [1-5]: ");

        try {
            int choice = Integer.parseInt(scanner.nextLine());

            switch (choice) {
                case 1:
                    // 查看当前作物状态
                    System.out.println("\n--- 当前作物状态 ---");
                    System.out.println("作物类型: " + cropGrowthMonitor.getStatus().get("cropType"));
                    System.out.println("生长阶段: " + cropGrowthMonitor.getStatus().get("stage"));
                    System.out.println("当前高度: " + cropGrowthMonitor.getStatus().get("height") + " cm");
                    break;

                case 2:
                    // 更新作物高度
                    System.out.print("请输入作物高度 (cm): ");
                    double height = Double.parseDouble(scanner.nextLine());
                    if (height < 0) {
                        System.out.println("高度必须大于等于0！");
                        return;
                    }

                    // 根据高度自动计算生长阶段
                    int stageIndex = 0;
                    if (height > 100) stageIndex = 6; // 成熟期
                    else if (height > 80) stageIndex = 5; // 结果期
                    else if (height > 50) stageIndex = 4; // 开花期
                    else if (height > 20) stageIndex = 3; // 生长期
                    else if (height > 5) stageIndex = 2; // 幼苗
                    else if (height > 0) stageIndex = 1; // 发芽

                    cropGrowthMonitor.updateGrowthStatus(height, stageIndex);
                    break;

                case 3:
                    // 更新作物生长阶段
                    System.out.println("选择生长阶段:");
                    System.out.println("0: 种子");
                    System.out.println("1: 发芽");
                    System.out.println("2: 幼苗");
                    System.out.println("3: 生长期");
                    System.out.println("4: 开花期");
                    System.out.println("5: 结果期");
                    System.out.println("6: 成熟期");
                    System.out.print("请输入阶段编号 (0-6): ");

                    int stage = Integer.parseInt(scanner.nextLine());
                    if (stage < 0 || stage > 6) {
                        System.out.println("阶段编号必须在0-6之间！");
                        return;
                    }

                    // 根据阶段自动设置合理高度范围
                    double defaultHeight = 0;
                    switch (stage) {
                        case 0: defaultHeight = 0; break;
                        case 1: defaultHeight = 2; break;
                        case 2: defaultHeight = 10; break;
                        case 3: defaultHeight = 40; break;
                        case 4: defaultHeight = 60; break;
                        case 5: defaultHeight = 90; break;
                        case 6: defaultHeight = 120; break;
                    }

                    cropGrowthMonitor.updateGrowthStatus(defaultHeight, stage);
                    break;

                case 4:
                    // 自动模拟生长
                    cropGrowthMonitor.autoMonitor();
                    break;

                case 5:
                    // 返回主菜单
                    return;

                default:
                    System.out.println("无效选择！");
            }

        } catch (NumberFormatException e) {
            System.out.println("请输入有效的数字！");
        }
    }
    // 查看设备列表
    // 显示设备列表
    private void displayEquipmentList() {
        System.out.println(manager.getEquipmentStatusList());
    }// 分配任务
    private void assignTask() {
        displayEquipmentList();
        System.out.print("\n请选择设备ID: ");
        String deviceId = scanner.nextLine();

        FarmMachine equipment = manager.getEquipmentById(deviceId);
        if (equipment == null) {
            System.out.println("设备不存在！");
            return;
        }

        System.out.println("\n===== 任务类型 =====");
        System.out.println("1. 耕地");
        System.out.println("2. 播种");
        System.out.println("3. 收割");
        System.out.println("4. 灌溉");
        System.out.println("5. 施肥");
        System.out.print("请选择任务类型 [1-5]: ");

        int taskType = scanner.nextInt();
        scanner.nextLine(); // 消耗换行符

        String taskName = "";
        String taskDescription = "";

        switch (taskType) {
            case 1:
                taskName = "耕地";
                System.out.print("请输入耕地面积(亩): ");
                taskDescription = "耕地 " + scanner.nextLine() + " 亩";
                break;
            case 2:
                taskName = "播种";
                System.out.print("请输入作物类型: ");
                taskDescription = "播种 " + scanner.nextLine();
                break;
            case 3:
                taskName = "收割";
                System.out.print("请输入作物类型: ");
                taskDescription = "收割 " + scanner.nextLine();
                break;
            case 4:
                taskName = "灌溉";
                System.out.print("请输入灌溉面积(亩): ");
                taskDescription = "灌溉 " + scanner.nextLine() + " 亩";
                break;
            case 5:
                taskName = "施肥";
                System.out.print("请输入肥料类型: ");
                taskDescription = "使用 " + scanner.nextLine() + " 施肥";
                break;
            default:
                System.out.println("无效任务类型！");
                return;
        }

        // 创建任务并分配
        Task task = new Task(taskName, taskDescription);
        manager.assignTask(deviceId, task);
        System.out.println("任务已分配给设备 " + deviceId);
    }
    // 处理安全事件
    public void handleSafetyEvent() {
        System.out.println("\n===== 处理安全事件 =====");
        System.out.println("1. 障碍物检测");
        System.out.println("2. 电子围栏越界");
        System.out.println("3. 设备故障");
        System.out.print("请选择安全事件类型 [1-3]: ");

        try {
            int eventType = Integer.parseInt(scanner.nextLine());
            String eventTypeName = "";
            String description = "";

            switch (eventType) {
                case 1:
                    inputPathAvoid();
                    break;
                case 2:
                    eventTypeName = "FENCE_BREACH";
                    System.out.print("请输入越界位置: ");
                    description = scanner.nextLine();
                    break;
                case 3:
                    eventTypeName = "EQUIPMENT_FAULT";
                    System.out.print("请输入故障描述: ");
                    description = scanner.nextLine();
                    break;
                default:
                    System.out.println("无效选择！");
                    return;
            }

            System.out.println("选择要处理事件的设备:");
            displayEquipmentList();
            System.out.print("请输入设备ID: ");
            String equipmentId = scanner.nextLine();

            safetyController.handleSafetyEvent(new SafetyEvent(eventTypeName, description, equipmentId));
            System.out.println("安全事件已提交处理");
        } catch (NumberFormatException e) {
            System.out.println("请输入有效的数字！");
        }
    }
    // 设备远程控制
    private void controlEquipment() {
        displayEquipmentList();
        System.out.print("\n请选择设备ID: ");
        String deviceId = scanner.nextLine();

        FarmMachine equipment = manager.getEquipmentById(deviceId);
        if (equipment == null) {
            System.out.println("设备不存在！");
            return;
        }
        remoteController = new RemoteController(equipment); //新增 初始化遥控器，绑定到所选设备
        System.out.println("\n===== 控制指令 =====");
        System.out.println("1. 启动设备");
        System.out.println("2. 停止设备");
        System.out.println("3. 紧急停止");
        System.out.println("4. 调整参数");
        System.out.print("请选择指令 [1-4]: ");

        int command = scanner.nextInt();
        scanner.nextLine(); // 消耗换行符

//        switch (command) {
//            case 1:
//                equipment.start();
//                break;
//            case 2:
//                equipment.stop();
//                break;
//            case 3:
//                equipment.emergencyStop();
//                break;
//            case 4:
//                System.out.print("请输入调整参数(如 speed=50): ");
//                String params = scanner.nextLine();
//                equipment.adjust(params);
//                break;
//            default:
//                System.out.println("无效指令！");
//        }
//    }
//
//}
        switch (command) {
            case 1:
                remoteController.startDevice();
                break;
            case 2:
                remoteController.stopDevice();
                break;
            case 3:
                remoteController.emergencyStop();
                break;
            case 4:
                System.out.print("请输入调整参数(如 speed=50): ");
                String params = scanner.nextLine();
                remoteController.adjustDevice(params);
                break;
            default:
                System.out.println("无效指令！");
        }
    }

    // 新增：撤销上一步操作
    private void undoLastOperation() {
        if (remoteController == null) {
            System.out.println("请先选择设备并执行操作！");
            return;
        }

        remoteController.pressUndo();
    }
}